<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>图文标注</title>
    <link href="css/ol.css" rel="stylesheet" type="text/css">
    <script src="js/ol.js" type="text/javascript"></script>
    <script src="js/jquery-1.11.2.min.js" type="text/javascript"></script>

    <style type="text/css">
        body, html, div, ul, li, iframe, p, img {
            border: none;
            padding: 0;
            margin: 0;
        }

        #mapCon {
            width: 100%;
            height: 580px;
            position: absolute;
        }

        #menu {
            width: 100%;
            height: 20px;
            padding: 5px 10px;
            font-size: 14px;
            font-family: "微软雅黑";
            left: 10px;
            text-align: center;
        }

        .checkbox {
            margin: 5px 15px;
        }

        .marker {
            width: 20px;
            height: 20px;
            border: 1px solid #088;
            border-radius: 10px;
            background-color: #0FF;
            opacity: 0.5;
        }

        .address {
            text-decoration: none;
            color: #aa3300;
            font-size: 14px;
            font-weight: bold;
            text-shadow: black 0.1em 0.1em 0.2em;
        }
    </style>
</head>
<body>
<div id="menu">
    选择标注类型后用鼠标在地图上点击添加标注：
    <label class="checkbox"><input type="radio" name="label" value="vector" />Vector Labels</label>
    <label class="checkbox"><input type="radio" name="label" value="overlay" />Overlay Labels</label>
</div>
<div id="mapCon">
</div>
<div id="label" style="display: none;">
    <div id="marker" class="marker" title="Marker">
        <a class="address" id="address" target="_blank" href="http://www.openlayers.org/">标注点</a>
    </div>
</div>
<script type="text/javascript">
    var beijing = ol.proj.fromLonLat([116.28, 39.54]);
    var wuhan = ol.proj.fromLonLat([114.21, 30.37]);

    //实例化Map对象加载地图,默认底图加载MapQuest地图
    var map = new ol.Map({
        layers: [
            new ol.layer.Tile({
                title: "天地图矢量图层",
                source: new ol.source.XYZ({
                    url: "http://t0.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=b74ca9a5dbd96fab6338ab9d239180fb",
                    wrapX: false
                })
            }),
            new ol.layer.Tile({
                title: "天地图矢量图层注记",
                source: new ol.source.XYZ({
                    url: "http://t0.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=b74ca9a5dbd96fab6338ab9d239180fb",
                    wrapX: false
                })
            })
        ],
        //地图容器div的ID
        target: 'mapCon',
        view: new ol.View({
            //地图初始中心点
            center: [130, 39],
            maxZoom: 19,
            minZoom: 1,
            zoom: 1
        })
    });

    /**
     * 创建矢量标注样式函数,设置image为图标ol.style.Icon
     * @param {ol.Feature} feature 要素
     */
    var createLabelStyle = function (feature) {
        return new ol.style.Style({
            image: new ol.style.Icon(
                /** @type {olx.style.IconOptions} */
                ({
                    anchor: [0.5, 60],
                    anchorOrigin: 'top-right',
                    anchorXUnits: 'fraction',
                    anchorYUnits: 'pixels',
                    offsetOrigin: 'top-right',
                    // offset:[0,10],
                    //图标缩放比例
                    // scale:0.5,
                    //透明度
                    opacity: 0.75,
                    //图标的url
                    src: 'blueIcon.png'
                })),
            text: new ol.style.Text({
                //位置
                textAlign: 'center',
                //基准线
                textBaseline: 'middle',
                //文字样式
                font: 'normal 14px 微软雅黑',
                //文本内容
                text: feature.get('name'),
                //文本填充样式（即文字颜色）
                fill: new ol.style.Fill({ color: '#aa3300' }),
                stroke: new ol.style.Stroke({ color: '#ffcc33', width: 2 })
            })
        });
    }

    //实例化Vector要素，通过矢量图层添加到地图容器中
    var iconFeature = new ol.Feature({
        geometry: new ol.geom.Point(beijing),
        //名称属性
        name: '北京市',
        //大概人口数（万）
        population: 2115
    });
    iconFeature.setStyle(createLabelStyle(iconFeature));
    //矢量标注的数据源
    var vectorSource = new ol.source.Vector({
        features: [iconFeature]
    });
    //矢量标注图层
    var vectorLayer = new ol.layer.Vector({
        source: vectorSource
    });
    map.addLayer(vectorLayer);

    // 实例化overlay标注，添加到地图容器中
    var marker = new ol.Overlay({
        position: wuhan,
        positioning: 'center-center',
        element: document.getElementById('marker'),
        stopEvent: false
    });
    map.addOverlay(marker);
    marker.getElement().title = "武汉市";
    var text = new ol.Overlay({
        position: wuhan,
        element: document.getElementById('address')
    });
    map.addOverlay(text);
    text.getElement().innerText = marker.getElement().title;

    //为地图容器添加单击事件监听
    map.on('click', function (evt) {
        var type = $("input[name='label']:checked").val();
        //鼠标单击点坐标
        var point = evt.coordinate;
        if (type == "vector") {
            //添加一个新的标注（矢量要素）
            addVectorLabel(point);
        }
        else if (type == "overlay") {
            //添加新的图文标注（overlay标注）
            addOverlayLabel(point);
        }
    });

    /**
     * 添加一个新的标注（矢量要素）
     * @param {ol.Coordinate} coordinate 坐标点
     */
    function addVectorLabel(coordinate) {
        //新建一个要素 ol.Feature
        var newFeature = new ol.Feature({
            //几何信息
            geometry: new ol.geom.Point(coordinate),
            //名称属性
            name: '标注点'
        });
        //设置要素的样式
        newFeature.setStyle(createLabelStyle(newFeature));
        //将新要素添加到数据源中
        vectorSource.addFeature(newFeature);
    }

    /**
     * 添加一个新的图文标注（overlay标注）
     * @param {ol.Coordinate} coordinate 坐标点
     */
    function addOverlayLabel(coordinate) {
        //新增div元素
        var elementDiv = document.createElement('div');
        elementDiv.className = "marker";
        elementDiv.title = "标注点";
        // 获取id为label的元素
        var overlay = document.getElementById('label');
        // 为ID为label的div层添加div子节点
        overlay.appendChild(elementDiv);
        //新增a元素
        var elementA = document.createElement("a");
        elementA.className = "address";
        elementA.href = "#";
        //设置文本
        setInnerText(elementA, elementDiv.title);
        // 新建的div元素添加a子节点
        elementDiv.appendChild(elementA);

        //实例化图文标注（图形+文本），添加到地图容器中
        var newMarker = new ol.Overlay({
            position: coordinate,
            positioning: 'center-center',
            element: elementDiv,
            stopEvent: false
        });
        map.addOverlay(newMarker);
        var newText = new ol.Overlay({
            position: coordinate,
            element: elementA
        });
        map.addOverlay(newText);
    }

    /**
     * 动态设置元素文本内容（兼容）
     **/
    function setInnerText(element, text) {
        if (typeof element.textContent == "string") {
            element.textContent = text;
        } else {
            element.innerText = text;
        }
    }
</script>
</body>
</html>